/*
 * Copyright (c) 2017 zhangcm. All Rights Reserved.
 */
package com.jnzc.ocr.common.utils;

import com.google.common.base.Optional;
import com.google.common.base.Preconditions;

import java.math.BigDecimal;

/**
 * @author zhangcm
 * @version 1.0, 2017/10/6
 */
public class CalculateUtils {

    private CalculateUtils(){}

    public static Integer def(Integer v){
        v = Optional.fromNullable(v).or(0);
        return v;
    }

    public static BigDecimal def(BigDecimal v){
        v = Optional.fromNullable(v).or(BigDecimal.ZERO);
        return v;
    }

    public static Integer neg(Integer v){
        v = Optional.fromNullable(v).or(0);
        Preconditions.checkArgument(v >= 0);
        return v > 0 ? v * -1 : v;
    }

    public static BigDecimal neg(BigDecimal v){
        v = Optional.fromNullable(v).or(BigDecimal.ZERO);
        Preconditions.checkArgument(v.compareTo(BigDecimal.ZERO) >= 0);
        return v.compareTo(BigDecimal.ZERO) > 0 ? v.multiply(new BigDecimal(-1)) : v;
    }

    public static Integer add(Integer v1, Integer v2){
        v1 = Optional.fromNullable(v1).or(0);
        v2 = Optional.fromNullable(v2).or(0);
        return v1 + v2;
    }

    public static BigDecimal add(BigDecimal v1, BigDecimal v2){
        v1 = Optional.fromNullable(v1).or(BigDecimal.ZERO);
        v2 = Optional.fromNullable(v2).or(BigDecimal.ZERO);
        return v1.add(v2);
    }

    public static Integer sub(Integer v1, Integer v2){
        v1 = Optional.fromNullable(v1).or(0);
        v2 = Optional.fromNullable(v2).or(0);
        return v1 - v2;
    }

    public static BigDecimal sub(BigDecimal v1, BigDecimal v2){
        v1 = Optional.fromNullable(v1).or(BigDecimal.ZERO);
        v2 = Optional.fromNullable(v2).or(BigDecimal.ZERO);
        return v1.subtract(v2);
    }

    public static BigDecimal sub(Integer v1, BigDecimal v2){
        v1 = Optional.fromNullable(v1).or(0);
        v2 = Optional.fromNullable(v2).or(BigDecimal.ZERO);
        return new BigDecimal(v1).subtract(v2);
    }

    public static BigDecimal mul(BigDecimal v1, Integer v2){
        v1 = Optional.fromNullable(v1).or(BigDecimal.ZERO);
        v2 = Optional.fromNullable(v2).or(0);
        return v1.multiply(new BigDecimal(v2));
    }

    public static BigDecimal mul(BigDecimal v1, BigDecimal v2){
        v1 = Optional.fromNullable(v1).or(BigDecimal.ZERO);
        v2 = Optional.fromNullable(v2).or(BigDecimal.ZERO);
        return v1.multiply(v2);
    }

    public static BigDecimal mul(BigDecimal v1, BigDecimal v2, Integer scale){
        v1 = Optional.fromNullable(v1).or(BigDecimal.ZERO);
        v2 = Optional.fromNullable(v2).or(BigDecimal.ZERO);
        return v1.multiply(v2).setScale(scale, BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal div(BigDecimal v1, BigDecimal v2, Integer scale){
        v1 = Optional.fromNullable(v1).or(BigDecimal.ZERO);
        v2 = Optional.fromNullable(v2).or(BigDecimal.ZERO);
        return v1.divide(v2, scale, BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal div(BigDecimal v1, Integer v2, Integer scale){
        v1 = Optional.fromNullable(v1).or(BigDecimal.ZERO);
        v2 = Optional.fromNullable(v2).or(0);
        return v1.divide(new BigDecimal(v2), scale, BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal div(Integer v1, Integer v2, Integer scale){
        v1 = Optional.fromNullable(v1).or(0);
        v2 = Optional.fromNullable(v2).or(0);
        return new BigDecimal(v1).divide(new BigDecimal(v2), scale, BigDecimal.ROUND_HALF_UP);
    }
}
